/**
 * SyntAttributes
 * --------------------------------------------------------------
 * 
 * - Is class will calculate the synthesized attributes.
 * 
 * - When a leaf node is reached, the path starts ascending, and values
 *   relation to restrictions on synthesized attributes are stored. 
 * 
 * @author 
 * @version 13-10-2013 
 */
package model.constraints.synthesized.attributes;

import java.util.ArrayList;
import java.util.Hashtable;

import model.constraints.inherited.Inters;


public class SyntAttributesXDF extends SyntAttributesAbstract  {

	public SyntAttributesXDF(){
		super();
	}

	/**
	 * This function will join synthesized attributes with "inters" recovered
	 * @param aux is SyntAttributes
	 * @param htIntersXfd 
	 * @param dataPos
	 * @return
	 */
	public SyntAttributesAbstract join (SyntAttributesAbstract aux, Hashtable<String,ArrayList<Inters>> htIntersXfd, String dataPos) {	
		
		ArrayList<Inters> newInters;
		Inters inters1N;
		Inters inters2N;	
		
		if (this.getInters().isEmpty()) {
			newInters = aux.getInters();			
			
		} else {			
		   if (aux.getInters().isEmpty()) {
			   newInters = this.getInters();			   			   
		   } else {			   	
				 newInters = new ArrayList<Inters>();				 				 				 
				 				 
				 // puts in newInters all intersections that are complete/calculated from syntattant  
				 for (Inters inters1: this.getInters()){					 					 
					 					 
					 if (!inters1.getDs().contains("#") && !inters1.getDc().equals("#")){				 						 						 						 
						 newInters.add(inters1);
					 } else { 						 										 						 

						 for (Inters inters2: aux.getInters()){
							 
							 inters1N = new Inters(inters1);
								
							 for(int i=0;i<inters2.getDs().size();i++){
								    if (inters1N.getDs().get(i).equals("#"))
			                               inters1N.setDs((String)inters2.getDs().get(i),i);    					
							  }
								 
						      if (inters1N.getDc().equals("#"))
			                        inters1N.setDc(inters2.getDc());    					
						   
						      if (!containsEq(newInters,inters1N)){
					    	        newInters.add(inters1N);
						      }
						  } 	
					 } 
					 
				 }				 				 
				 
				 // puts in newInters all intersections that are complete/calculated from syntatt  
				 for (Inters inters2: aux.getInters()) {					
					 if (!inters2.getDs().contains("#") && !inters2.getDc().equals("#")){
						   newInters.add(inters2);
					 } else { 	   							 						   						   
						   for (Inters inters1: this.getInters()) {								   	
							   
							   	  inters2N = new Inters(inters2);
							   							   
			  			          for(int i=0;i<inters1.getDs().size();i++) {
				  					    if (inters2N.getDs().get(i).equals("#"))
				                                 inters2N.setDs((String)inters1.getDs().get(i),i);				  					    				  					    
			  			          }
				  			       
			  			          if (inters2N.getDc().equals("#"))
			  			        	  inters2N.setDc(inters1.getDc());    						
			  			          
			  			          //verifica igualdade
			  			          if (!containsEq(newInters,inters2N)) {
			  			        	  newInters.add(inters2N);
			  			          }
		                   }
						   
		  	         }
					 
				 }
				 											
	  	   	} 
		}    	    	   
	   	    
		if (!newInters.isEmpty()){
	       htIntersXfd.put(dataPos,newInters);
	    }   	    					   
		
	    aux.inters = new ArrayList<Inters>();
		this.setInters(newInters);
		
		return this;
	}

	/***
	 * This function checks if has two inters equals
	 * @param newInters
	 * @param it
	 * @return if inters are equal return true
	 */
	public Boolean containsEq (ArrayList<Inters> newInters, Inters it) {
		
		for (Inters inter: newInters) {	     	  
			if (inter.getDs().equals(it.getDs()) && inter.getDc().equals(it.getDc()))
				return true;
		}    		  	         
		return false;
	}	
	
}